package com.example.uupaymuch.controller.notice.wudi;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.springframework.stereotype.Component;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.*;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

@Component
@Slf4j
public class TransferComponent {

//    private final String noticeTransfer = "http://192.168.50.145:27003/api/transfer/notify/brazilpay/wudipay";
        private final String noticeTransfer = "http://localhost:27003/api/transfer/notify/brazilpay/wudipay";
//    private final String noticeTransfer = "https://pay-india.ssonicpay.com/api/transfer/notify/brazilpay/wudipay";
    private static final String HMAC_SECRET = "123456789"; // 从安全配置中获取

    //    private final Random random = new Random();
    private final double successProbability = 0.5; // 50% 的成功概率
    private final CloseableHttpClient httpClient;

    public TransferComponent() {
        // 创建带有连接池的 HttpClient 实例
        this.httpClient = HttpClients.custom()
                .setMaxConnTotal(200)  // 设置最大连接数
                .setMaxConnPerRoute(200)  // 设置每个路由的最大连接数
                .build();
    }

    ScheduledThreadPoolExecutor scheduledThreadPoolExecutorTransfer =
            new ScheduledThreadPoolExecutor(Runtime.getRuntime().availableProcessors() * 2);
    private static final Map<String, Object> PARAMS;
    private static final Map<String, Object> ACCOUNT;

    // 静态初始化块
    static {
        PARAMS = new HashMap<>();
        PARAMS.put("performed_at", "2024-10-15T01:32:17.000000Z");
        PARAMS.put("addressing_key", "35186778885");
        PARAMS.put("reason", "Pix key search has failed");
        PARAMS.put("provider_account", "11");
        PARAMS.put("recipient_document_number", "35186778885");
        PARAMS.put("fee", 0.05);
        PARAMS.put("created_at", "2024-10-15T01:32:17.000000Z");
        PARAMS.put("uuid", "69cc1a30-3fc7-44e7-90ed-11a68af9edcc");
        PARAMS.put("addressing_key_type", "CPF");
        PARAMS.put("workspace_id", 67);
        PARAMS.put("initialization_type", "DICT");
        PARAMS.put("updated_at", "2024-10-15T01:32:17.000000Z");
        PARAMS.put("provider", "DOCK");
        PARAMS.put("id", 12169671);
        PARAMS.put("amount", 500);
        PARAMS.put("account_id", 398);
        PARAMS.put("error_code", "OUT002");
        // 初始化 ACCOUNT 对象
        ACCOUNT = new HashMap<>();
        ACCOUNT.put("workspace_id", 66);
        ACCOUNT.put("updated_at", "2024-10-03T16:02:06.000000Z");
        ACCOUNT.put("name", "Default");
        ACCOUNT.put("deny_legal_entities_cash_outs", true);
        ACCOUNT.put("created_at", "2024-06-13T00:59:45.000000Z");
        ACCOUNT.put("id", 99);
        ACCOUNT.put("customer_id", 299);
        ACCOUNT.put("plan_id", 497);
        ACCOUNT.put("status", "DONE");
    }


    public void doNotifyTransfer(String txid, String payStatusStr, String amount) {
        scheduledThreadPoolExecutorTransfer.schedule(() -> {
            // 执行推送
            try {
                notifyPaymentTransfer(txid, payStatusStr, amount);
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }, 1, TimeUnit.SECONDS);
    }

    public void notifyPaymentTransfer(String payOrderId, String payStatusStr, String amount) throws IOException {
        // 构建请求体参数
        Map<String, Object> params = new HashMap<>(PARAMS); // 深拷贝
        params.put("correlation_id", payOrderId);
        params.put("account", new HashMap<>(ACCOUNT)); // 深拷贝
        params.put("status", payStatusStr);
        params.put("amount", amount);

        try {
            log.info("代付回调请求 body:{}, url:{}", params, noticeTransfer);
            HttpPost request = new HttpPost(noticeTransfer);
            String json = new ObjectMapper().writeValueAsString(params);
            StringEntity entity = new StringEntity(json);
            entity.setContentType("application/json");
            request.setEntity(entity);

            String hmacsha256Signature = generateHMACSHA256Signature(json, HMAC_SECRET); // 从配置中获取密钥
            request.setHeader("Signature", hmacsha256Signature);

            httpClient.execute(request);
        } catch (NoSuchAlgorithmException | InvalidKeyException | JsonProcessingException e) {
            log.error("Error generating HMAC or processing JSON", e);
            throw new RuntimeException("Error during payment transfer notification", e);
        }
    }


    public static String generateHMACSHA256Signature(String data, String secret)
            throws NoSuchAlgorithmException, InvalidKeyException {
        Mac mac = Mac.getInstance("HmacSHA256");
        SecretKeySpec secretKeySpec = new SecretKeySpec(secret.getBytes(StandardCharsets.UTF_8), "HmacSHA256");
        mac.init(secretKeySpec);

        byte[] rawHmac = mac.doFinal(data.getBytes(StandardCharsets.UTF_8));

        // 将字节数组转换为十六进制字符串
        StringBuilder sb = new StringBuilder(2 * rawHmac.length);
        for (byte b : rawHmac) {
            sb.append(String.format("%02x", b));
        }
        return sb.toString();
    }
}
